#include "csemp.h"

// 用信号量给共享内存加锁

struct gril
{
    int no;
    char name[51];   // 不能用string
};

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cout << "Using: ./demp01 no name" << std::endl;
        return -1;
    }
    
    // 1、创建/获取共享内存，键值key为0x5005，其他值也可以
    int shmid = shmget(0x5005, sizeof(gril), 0640|IPC_CREAT);
    if (shmid == -1)
    {
        std::cout << "shmget(0x5005) failed" <<std::endl;
        return -1;
    }
    std::cout << "shmid=" << shmid <<std::endl;

    // 2、把共享内存链接到当前进程的地址空间
    gril *ptr = (gril *)shmat(shmid, 0, 0);
    if (ptr == (void *)-1)
    {
        std::cout << "shmat failed" <<std::endl;
        return -1;
    }
    
    // 创建初始化二元信号量
    Csemp mutex;
    if (!mutex.init(0x5005))
    {
        std::cout << "mutex.init(0x5005) failed" <<std::endl;
        return -1;
    }

    std::cout << "申请加锁..." <<std::endl;
    mutex.wait();
    std::cout << "加锁成功..." <<std::endl;
    
    // 3、使用共享内存，对共享内存进行读/写
    // 打印原始值
    std::cout << "原值:no=" << ptr->no << ", name=" << ptr->name <<std::endl;  
    ptr->no = std::atoi(argv[1]);
    strcpy(ptr->name, argv[2]);
    std::cout << "新值:no=" << ptr->no << ", name=" << ptr->name <<std::endl; 
    sleep(10);
    
    // 解锁
    mutex.post();
    std::cout << "解锁成功..." <<std::endl;

    /*
        查看信号量 ipcs -s
        删除信号量 ipcrm sem 信号量id
        查看共享内存 ipcs -m
        删除共享内存 ipcrm -m 共享内存id
    */ 

    // 4、把共享内存从当前进程中分离
    shmdt(ptr);

    // 5、删除共享内存
    if (shmctl(shmid, IPC_RMID, 0) == -1)
    {
        std::cout << "shmctl failed" <<std::endl;
        return -1;
    }
    
}


